package sy4_Creational_Pattern.factory.abstractFactory.other;
/*
 * 工厂方法模式案例案例中，不同具体工厂都生产同一种产品。
 * 抽象工厂模式案例中，存在产品等级结构和产品族概念。
 * 
 * 产品等级结构由不同工厂生产的同一类型产品组成，如海尔电视机——TCL电视机...。
 * 产品等级结构：指产品的继承结构，如抽象的电视机与具体品牌的电视机之间构成了一个产品等级结构。
 * 
 * 产品族：同一工厂生产、位于不同产品等级结构中的的不同产品，如海尔电视机——海尔空调器...
 *        简明地说，产品族是指同一工厂生产多种产品。
 * 
 * 工厂方法模式只有一个产品等级结构，因此，工厂方法模式是抽象工厂模式的退化。
 * 
 * 如果增加新的产品（如洗衣机），则需要添加相应的接口Washer及其实现类HaierWasher和TCLWasher。
 * 同时，还需要在电子工厂接口EFactory添加Washer的抽象方法，在EFactory的实现类里实现新增的接口方法。
 * 因此，抽象工厂模式属于对象创建型模式。抽象工厂模式不支持添加新的产品类别。
 * 
 * 如果增加新的品牌（产品簇），如Sony工厂，只需要增加该工厂生产的产品类，则符合开闭原则（如同工厂方法模式）。
 * 
 */


interface Television {  //抽象电视产品接口
    public void play();
}

class HaierTelevision implements Television {
    @Override
    public void play() {
        System.out.println("海尔电视机播放中......");
    }
}

class TCLTelevision implements Television {
    @Override
    public void play() {
        System.out.println("TCL电视机播放中......");
    }
}

interface AirConditioner {   //抽象空调产品接口
    public void changeTemperature();
}


/*interface Washer {   //抽象洗衣机产品接口
    public void wash();
}*/

class HaierAirConditioner implements AirConditioner {
	
	@Override
    public void changeTemperature() {
        System.out.println("海尔空调温度改变中......");
    }
}


class TCLAirConditioner implements AirConditioner {
	
	@Override
    public void changeTemperature() {
        System.out.println("TCL空调温度改变中......");
    }
}

/*class HaierWasher implements Washer {
	
	@Override
    public void wash() {
        System.out.println("海尔洗衣机正在工作中......");
    }
}

class TCLWasher implements Washer {
	
	@Override
    public void wash() {
        System.out.println("TCL洗衣机正在工作中......");
    }
}*/

interface EFactory { // 电子工厂接口
	
    public Television produceTelevision(); // 电视
    public AirConditioner produceAirConditioner(); // 空调
    
    //public Washer produceWasher(); //洗衣机
}

class HaierFactory implements EFactory {   // 海尔电子工厂接口

    @Override
    public Television produceTelevision() {
        System.out.println("海尔工厂生产海尔电视机");
        return new HaierTelevision();
    }

    @Override
    public AirConditioner produceAirConditioner() {
        System.out.println("海尔工厂生产海尔空调");
        return new HaierAirConditioner();
    }
    
    /*@Override
    public Washer produceWasher() {
        System.out.println("海尔工厂生产海尔洗衣机");
        return new HaierWasher();
    } */  
}

class TCLFactory implements EFactory {   // TCL电子工厂接口

    @Override
    public Television produceTelevision() {
        System.out.println("TCL工厂生产TCL电视机");
        return new TCLTelevision();
    }

    @Override
    public AirConditioner produceAirConditioner() {
        System.out.println("TCL工厂生产TCL空调");
        return new TCLAirConditioner();
    }

	/*@Override
	public Washer produceWasher() {
		System.out.println("TCL工厂生产TCL洗衣机");
		return new TCLWasher();
	}*/
}

//增加Sony电子工厂，只需要增加相应的产品
class SonyFactory implements EFactory {   // Sony电子工厂
    @Override
    public Television produceTelevision() {
        System.out.println("Sony工厂生产Sony电视机");
        return new SonyTelevision();
    }
    @Override
    public AirConditioner produceAirConditioner() {
        System.out.println("Sony工厂生产Sony空调");
        return new SonyAirConditioner();
    }
}
class SonyTelevision implements Television {  //Sony产品
    @Override
    public void play() {
        System.out.println("Sony电视机播放中......");
    }
}
class SonyAirConditioner implements AirConditioner {  //Sony产品
	@Override
    public void changeTemperature() {
        System.out.println("Sony空调温度改变中......");
    }
}

public class Client {

    static EFactory factory;  //定义工厂接口类型的对象
    
    //定义产品族对象
    static Television tv;  
    static AirConditioner ac;
    //static Washer washer;

    public static void main(String args[]) {
    	
        factory = new HaierFactory();  //创建Haier工厂
        tv = factory.produceTelevision();
        tv.play();
        ac = factory.produceAirConditioner();
        ac.changeTemperature();
        /*washer=factory.produceWasher();
        washer.wash();*/
        System.out.println("======================");

        try { // 适当修改配置文件，做运行测试
            factory = (EFactory) XMLUtil.getBean();
            tv = factory.produceTelevision();
            tv.play();
            ac = factory.produceAirConditioner();
            ac.changeTemperature();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}